package au.com.acpfg.phylogeny.writer;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import org.knime.core.data.DataCell;
import org.knime.core.data.DataRow;
import org.knime.core.data.DataTableSpec;
import org.knime.core.data.RowIterator;
import org.knime.core.node.BufferedDataTable;
import org.knime.core.node.CanceledExecutionException;
import org.knime.core.node.ExecutionContext;
import org.knime.core.node.ExecutionMonitor;
import org.knime.core.node.InvalidSettingsException;
import org.knime.core.node.NodeLogger;
import org.knime.core.node.NodeModel;
import org.knime.core.node.NodeSettingsRO;
import org.knime.core.node.NodeSettingsWO;
import org.knime.core.node.defaultnodesettings.SettingsModelString;
import au.com.acpfg.align.muscle.FormattedRenderer;
import au.com.acpfg.align.muscle.MultiAlignmentCell;
/**
* This is the model implementation of AlignmentWriter.
* Saves one or more alignments to disk (ie. AlignmentCell's). The filename comes from the RowID
* with a suitable extension for the desired format (.aln, .clustalw etc.)
*
* @author Andrew Cassin
*/
public class AlignmentWriterNodeModel extends NodeModel {
// the logger instance
private static final NodeLogger logger = NodeLogger
.getLogger(AlignmentWriterNodeModel.class);
static final String CFGKEY_FORMAT = "alignment-format";
static final String CFGKEY_COLUMN = "alignment-column";
static final String CFGKEY_FOLDER = "destination-folder";
private final SettingsModelString m_format = new SettingsModelString(CFGKEY_FORMAT, "Clustal");
private final SettingsModelString m_column = new SettingsModelString(CFGKEY_COLUMN, "Alignment");
private final SettingsModelString m_folder = new SettingsModelString(CFGKEY_FOLDER, "c:/temp");
/**
* Constructor for the node model.
*/
protected AlignmentWriterNodeModel() {
super(1, 0);
}
/**
* {@inheritDoc}
*/
@Override
protected BufferedDataTable[] execute(final BufferedDataTable[] inData,
final ExecutionContext exec) throws Exception {
RowIterator it = inData[0].iterator();
int col_idx = inData[0].getDataTableSpec().findColumnIndex(m_column.getStringValue());
if (col_idx < 0) {
throw new Exception("Cannot find column: "+m_column.getStringValue()+", re-configure the node?");
}
while (it.hasNext()) {
DataRow r = it.next();
DataCell aln_cell = r.getCell(col_idx);
String basename = r.getKey().getString();
if (aln_cell instanceof MultiAlignmentCell) {
MultiAlignmentCell ac = (MultiAlignmentCell) aln_cell;
save_alignment(new File(m_folder.getStringValue(), basename + ".aln"), ac, m_format.getStringValue().toLowerCase());
}
}
return null;
}
/**
* Saves the specified alignment cell (instance of MultiAlignmentCell) in the specified file, with the specified format.
* An error is thrown if the alignment is not valid for the chosen format or cannot be saved for any reason
*
* @param file file to save to
* @param ac cell to save
* @param alignment_format must be in all lowercase eg. clustal, nexus etc...
* @throws IOException thrown upon exception eg. disk full
*/
private void save_alignment(File file, MultiAlignmentCell ac, String alignment_format) throws IOException, UnsupportedAlignmentException {
if (alignment_format.startsWith("clustal")) {
String txt = ac.getFormattedAlignment(FormattedRenderer.FormatType.F_CLUSTALW);
PrintWriter pw = new PrintWriter(new FileOutputStream(file));
pw.print(txt);
pw.close();
} else {
throw new UnsupportedAlignmentException("Unsupported format "+alignment_format);
}
}
/**
* {@inheritDoc}
*/
@Override
protected void reset() {
}
/**
* {@inheritDoc}
*/
@Override
protected DataTableSpec[] configure(final DataTableSpec[] inSpecs)
throws InvalidSettingsException {
return null;
}
/**
* {@inheritDoc}
*/
@Override
protected void saveSettingsTo(final NodeSettingsWO settings) {
m_format.saveSettingsTo(settings);
m_column.saveSettingsTo(settings);
m_folder.saveSettingsTo(settings);
}
/**
* {@inheritDoc}
*/
@Override
protected void loadValidatedSettingsFrom(final NodeSettingsRO settings)
throws InvalidSettingsException {
m_format.loadSettingsFrom(settings);
m_column.loadSettingsFrom(settings);
m_folder.loadSettingsFrom(settings);
}
/**
* {@inheritDoc}
*/
@Override
protected void validateSettings(final NodeSettingsRO settings)
throws InvalidSettingsException {
m_format.validateSettings(settings);
m_column.validateSettings(settings);
m_folder.validateSettings(settings);
}
/**
* {@inheritDoc}
*/
@Override
protected void loadInternals(final File internDir,
final ExecutionMonitor exec) throws IOException,
CanceledExecutionException {
// TODO load internal data.
// Everything handed to output ports is loaded automatically (data
// returned by the execute method, models loaded in loadModelContent,
// and user settings set through loadSettingsFrom - is all taken care
// of). Load here only the other internals that need to be restored
// (e.g. data used by the views).
}
/**
* {@inheritDoc}
*/
@Override
protected void saveInternals(final File internDir,
final ExecutionMonitor exec) throws IOException,
CanceledExecutionException {
// TODO save internal models.
// Everything written to output ports is saved automatically (data
// returned by the execute method, models saved in the saveModelContent,
// and user settings saved through saveSettingsTo - is all taken care
// of). Save here only the other internals that need to be preserved
// (e.g. data used by the views).
}
}